package com.chipcoo.services;

import com.alibaba.fastjson.JSON;
import com.chipcoo.UserPrincipal;
import com.chipcoo.dao.impl.*;
import com.chipcoo.models.gen.*;
import com.chipcoo.shiro.session.mgt.UserSession;
import com.chipcoo.utils.SecurityUtils;
import com.chipcoo.utils.StringUtils;
import com.xcode.mybatis.mapper.Example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class UserService {
    @Autowired
    private PassportMapperImpl passportMapper;
    @Autowired
    private UserMapperImpl userMapper;
    @Autowired
    private UserLoginMapperImpl userLoginMapper;
    @Autowired
    private UserProfileMapperImpl userProfileMapper;


    /**
     * 绑定指定账号,并返回passportID
     * @param username
     * @param passportType
     * @param userID
     * @return
     */
    public int bindPassport(String username,int passportType,int userID,Object objectToJSON){
        Passport found = getAuthenticationPassport(username,passportType);
        if(null==found){
            Passport entity =new Passport();
            entity.setPrincipal(username);
            entity.setPassportType(passportType);

            entity.setConfirmed(true);
            entity.setUserID(userID);
            if(null!=objectToJSON){
                String json = JSON.toJSONString(objectToJSON);
                entity.setJsonSchema(json);

            }
            passportMapper.insertSelective(entity);
            return entity.getId();
        }else if(null==found.getUserID()||1>found.getUserID()) {
            found.setConfirmed(true);
            found.setUserID(userID);
            if(null!=objectToJSON){
                String json = JSON.toJSONString(objectToJSON);
                found.setJsonSchema(json);
            }
            passportMapper.updateByPrimaryKeySelective(found);
            return found.getId();
        }
        return 0;
    }

    public Passport getAuthenticationPassport(int id) {
        return passportMapper.selectByPrimaryKey(id);
    }
    /**
     * 获取凭证
     * @param username
     * @param passportType 1=手机 2=邮件 3=微信
     * @return
     */
    public Passport getAuthenticationPassport(String username, int passportType){
        Passport passport =  passportMapper.selectByPrincipalAndType(username,passportType);
        if(null!=passport){
            if(null==passport.getUserID()|| 1>passport.getUserID() || !passport.getConfirmed())
                return null;
        }
        return passport;
    }

    /**
     * 获取用户基本信息(含登录密码,用于进一步认证)
     * @param userID
     * @return
     */
    public User getUser(Integer userID) {
        if(userID>0)
            return userMapper.selectByPrimaryKey(userID);
        return null;
    }


    /**
     * 获取用户基本资料
     * @param userID
     * @return
     */
    public UserProfile getProfile(Integer userID){
        return userProfileMapper.selectByPrimaryKey(userID);
    }
    public void createUpdateProfile(UserProfile profile){
        //// TODO: 2016/5/11  
        if(null!=profile){
            if( 0== userProfileMapper.updateByPrimaryKeySelective(profile))
            {
                profile.setCreatedAt(new Date());
                userProfileMapper.insertSelective(profile);
            }
        }
    }

    /**
     * 返回会话Principal
     * @param userID
     * @return
     */
    public UserPrincipal getPrincipal(Integer userID){
        User user = getUser(userID);
        if(null==user) return null;
        UserProfile profile = getProfile(userID);
        String loginName =String.valueOf(userID);
        return  new UserPrincipal(loginName, user ,profile);
    }

    @Transactional
    public boolean createPassport(String username,String password,boolean isPhone) {

        User user = new User();
        user.setPasswordHash(password);
        userMapper.insertSelective(user);

        Passport exists = null;
        if (isPhone) exists = getAuthenticationPassport(username, 1);
        else exists = getAuthenticationPassport(username, 2);
        if(null==exists) {
            Passport passport = new Passport();
            passport.setUserID(user.getId());
            passport.setPrincipal(username);
            passport.setPassportType(isPhone ? 1 : 2);
            passport.setConfirmed(true);
            passportMapper.insertSelective(passport);
            return null!=passport.getId() && passport.getId()>0;
        }else{
            if(null==exists.getUserID()||exists.getUserID()<1){
                exists.setUserID(user.getId());
                exists.setConfirmed(true);
                passportMapper.updateByPrimaryKeySelective(exists);
                return true;
            }
            return false;
        }


    }

    public boolean changePassword(int userID,String newPassword){
        User user = new User();
        user.setId(userID);
        user.setPasswordHash(newPassword);
        userMapper.updateByPrimaryKeySelective(user);
        return true;
    }



    /**
     * 登录成功
     * @param user
     */
    @Transactional
    public void loginSuccess(int passportID,User user) {
        boolean shouldUpdate = false;
        User updateSelective = new User();


        if (user.getLockoutEnabled()) {
            updateSelective.setLockoutEnabled(false);
            shouldUpdate = true;
        }

        if (user.getAccessFailedCount() > 0) {
            updateSelective.setAccessFailedCount(0);
            shouldUpdate = true;
        }
        if (shouldUpdate) {
            updateSelective.setId(user.getId());
            userMapper.updateByPrimaryKeySelective(updateSelective);

        }


        UserLogin userLogin = new UserLogin();
        userLogin.setCreatedAt(new Date());
        userLogin.setUserID(user.getId());
        userLogin.setPassportID(passportID);

        Finger finger = com.chipcoo.utils.SecurityUtils.getCurrentFinger();
        if(null!=finger) {
            userLogin.setFingerID(finger.getId());
        }
        org.apache.shiro.session.Session session = SecurityUtils.getSession(false);
        if(null!=session) {
            if(session instanceof UserSession) {
                userLogin.setServerHost( ((UserSession)session).getServerHost() );
            }
            userLogin.setClientIP(StringUtils.ip2long(session.getHost()));
        }

        userLoginMapper.insertSelective(userLogin);
    }

    /**
     * 登录失败
     * @param user
     */
    public void loginFailed(User user){
        User updateSelective = new User();
        updateSelective.setId(user.getId());
        updateSelective.setAccessFailedCount(user.getAccessFailedCount()+1);

        if(updateSelective.getAccessFailedCount()>10){
            updateSelective.setLockoutEnabled(true);

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MINUTE,30);
            updateSelective.setLockoutEnd(calendar.getTime());
        };
        userMapper.updateByPrimaryKeySelective(updateSelective);
    }
    //endregion

    /**
     * 通过userID获取所有已确认的凭证
     * @param userID
     * @return
     */
    public List<Passport> selectPassport(int userID,boolean excludeNoConfirmed){
        Example example = new Example();
        example.createCriteria().eq("userID",userID);
        if(excludeNoConfirmed){
            example.createCriteria().eq("confirmed",true);
        }

        return passportMapper.selectByExample(example);
    }


}